package cn.graydove.bot.service.impl;

import cn.graydove.bot.model.entity.ActivationCode;
import cn.graydove.bot.model.entity.Advance;
import cn.graydove.bot.repository.ActivationCodeRepository;
import cn.graydove.bot.repository.AdvanceRepository;
import cn.graydove.bot.service.AdvanceService;
import cn.graydove.bot.utils.ShaUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;

@Slf4j
@Service
public class AdvanceServiceImpl implements AdvanceService {

    private AdvanceRepository advanceRepository;

    private ActivationCodeRepository activationCodeRepository;

    public AdvanceServiceImpl(AdvanceRepository advanceRepository, ActivationCodeRepository activationCodeRepository) {
        this.advanceRepository = advanceRepository;
        this.activationCodeRepository = activationCodeRepository;
    }

    @Override
    public String createActivationCode(long validityTime) {
        ActivationCode code;
        code = new ActivationCode(ShaUtil.UUID().toUpperCase(), validityTime);
        code = activationCodeRepository.save(code);
        log.info("创建激活码：{}", code.getCode());
        return code.getCode();
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public boolean activate(long groupNumber, String code) {
        Advance advance = findOrCreateByGroupNumber(groupNumber);

        ActivationCode activationCode = activationCodeRepository.findByCode(code.toUpperCase());

        if (activationCode.getGroupUser() != null) {
            return false;
        }
        activationCode.setGroupUser(groupNumber);
        activationCode = activationCodeRepository.save(activationCode);

        advance.setActivationCode(activationCode);
        advance.setActivateTime(new Date());
        advance.setValidityTime(activationCode.getValidityTime());
        advance = advanceRepository.save(advance);
        log.info("QQ群{}使用激活码{}成功激活", groupNumber, advance.getActivationCode());
        return true;
    }

    @Override
    public boolean isActivated(Long groupNumber) {
        Advance advance = findOrCreateByGroupNumber(groupNumber);
        return isActivated(advance);
    }

    @Override
    public boolean isActivated(Advance advance) {
        if (advance == null || advance.getActivationCode() == null || advance.getValidityTime() == null || advance.getActivateTime() == null) {
            return false;
        }
        if (advance.getValidityTime() > 0) {
            return advance.getActivateTime().getTime() + advance.getValidityTime() >= new Date().getTime();
        }
        return true;
    }

    @Override
    @Transactional
    public void addImageNumber(long groupNumber) {
        Advance advance = findOrCreateByGroupNumber(groupNumber);
        advance.setRequestImageNumber(advance.getRequestImageNumber() + 1);
        advanceRepository.save(advance);
    }

    @Override
    public void ebbImageNumber(long groupNumber) {
        Advance advance = findOrCreateByGroupNumber(groupNumber);
        advance.setRequestImageNumber(advance.getRequestImageNumber() - 1);
        advanceRepository.save(advance);
    }

    @Override
    @Transactional
    public Advance findOrCreateByGroupNumber(Long groupNumber) {
        Advance advance = advanceRepository.findByGroupNumber(groupNumber);
        if (advance == null) {
            advance = new Advance(groupNumber);
            advance = advanceRepository.save(advance);
        }
        return advance;
    }

    @Override
    @Transactional
    public void clearImg() {
        advanceRepository.clearImg();
    }
}
